#include "ai_service_proxy.h"
#include "ai_service_log.h"
#include "ai_service_errors.h"

using namespace OHOS::HiviewDFX;

namespace OHOS {
namespace AIS {
namespace {
    constexpr HiLogLabel LABEL = {LOG_CORE, AIS_LOG_DOMAIN, "AIServiceProxy"};
}

int32_t AIServiceProxy::Init(std::string& modelPath, int32_t* modelId)
{
    AIS_HILOGD("Init start.");

    CHKPTR(modelId, RETCODE_NULL_PARAM);

    MessageParcel data;
    MessageParcel reply;
    MessageOption option;

    sptr<IRemoteObject> remote = Remote();
    CHKPTR(remote, RETCODE_NULL_PARAM);

    data.WriteString(modelPath);
    int32_t ret = remote->SendRequest(INIT, data, reply, option);
    if (ret != RETCODE_SUCCESS)
    {
        AIS_HILOGE("sendRequest failed, ret:%{public}d", ret);
        return RETCODE_PROXY_SEND_REQUEST_FAILED;
    }
    AIS_HILOGD("sendRequest success.");

    int32_t errorCode = reply.ReadInt32();
    *modelId = reply.ReadInt32();
    if (*modelId == -1 || errorCode != RETCODE_SUCCESS)
    {
        AIS_HILOGE("Build model failed, ret:%{public}d", errorCode);
        return errorCode;
    }
    
    AIS_HILOGD("Init end.");
    return RETCODE_SUCCESS;
}

int32_t AIServiceProxy::Process(const int32_t modelId, PicDesc& picDesc, std::string& picData, InferResult& result)
{
    AIS_HILOGD("Process start.");
    CHKID(modelId, RETCODE_INVALID_PARAM);

    MessageParcel data;
    MessageParcel reply;
    MessageOption option;

    sptr<IRemoteObject> remote = Remote();
    CHKPTR(remote, RETCODE_NULL_PARAM);

    AIS_HILOGD("picData size:  %{public}d", (int)picData.size());
    data.WriteInt32(modelId);
    data.WriteRawData((const void *)&picDesc, sizeof(PicDesc));
    data.WriteString(picData);

    int32_t ret = remote->SendRequest(PROCESS, data, reply, option);
    if (ret != RETCODE_SUCCESS)
    {
        AIS_HILOGE("sendRequest failed, ret:%{public}d", ret);
        return RETCODE_PROXY_SEND_REQUEST_FAILED;
    }
    AIS_HILOGD("sendRequest success.");

    int32_t errorCode = reply.ReadInt32();
    if (errorCode != RETCODE_SUCCESS)
    {
        AIS_HILOGE("Model Predict failed, ret:%{public}d", errorCode);
        return errorCode;
    }
    result = *((InferResult *)reply.ReadRawData(sizeof(InferResult)));

    AIS_HILOGD("Process end.");
    return RETCODE_SUCCESS;
}

int32_t AIServiceProxy::DeInit()
{
    AIS_HILOGD("DeInit start.");

    MessageParcel data;
    MessageParcel reply;
    MessageOption option;

    sptr<IRemoteObject> remote = Remote();
    CHKPTR(remote, RETCODE_NULL_PARAM);

    int32_t ret = remote->SendRequest(DEINIT, data, reply, option);
    if (ret != RETCODE_SUCCESS)
    {
        AIS_HILOGE("sendRequest failed, ret:%{public}d", ret);
        return RETCODE_PROXY_SEND_REQUEST_FAILED;
    }

    int32_t errorCode = reply.ReadInt32();
    if (errorCode != RETCODE_SUCCESS)
    {
        AIS_HILOGE("Destroy model failed, ret:%{public}d", errorCode);
        return errorCode;
    }

    AIS_HILOGD("DeInit end.");
    return RETCODE_SUCCESS;
}
}  // namespace AIS    
}  // namespace OHOS